<template>
  <div class="associativeSelectGroup-container">
    <div
      v-for="(item, index) in computedSourceMap"
      :key="item.type"
      style="display: flex"
    >
      <slot :name="'space_' + index"></slot>
      <bjSelect
        v-bind="$attrs"
        v-on="$listeners"
        :loading="loading[item.type]"
        :allowClear="item.allowClear || true"
        :placeholder="item.placeholder || '请选择'"
        :replaceFields="item.replaceFields"
        :dataResource="list[item.type] || []"
        :mode="item.mode"
        v-model="choosedValue[item.type]"
        @change="conditionChange($event, item.type)"
      >
      </bjSelect>
    </div>
    <slot :name="'space_' + computedSourceMap.length"></slot>
    <bjRangeCalendar
      v-bind="$attrs"
      v-on="$listeners"
      @ok="calendarOk"
      @change="calendarChange"
      v-if="map.some((v) => v.type == 'calendar')"
    ></bjRangeCalendar>
    <slot :name="'space_' + (computedSourceMap.length + 1)"></slot>
  </div>
</template>

<script>
//基于a-select二次封装组件
import bjSelect from "@/components/bj-select";
//基于a-range-picker二次封装组件
import bjRangeCalendar from "@/components/bj-range-calendar";
//获取登录信息
import { getLoginData } from "@/tools";
//获取标段列表接口
import {
  getTestUnitByUserIdAndTenantCode,
  getBlockList,
} from "@/api/wisdom-beam/trial-app";
export default {
  name: "AssociativeSelectGroup",
  mode: {
    prop: "value",
    event: "input",
  },
  props: {
    map: {
      type: Array,
      default: () => {
        return [
          // 检测单位
          {
            type: "block",
            mode: "default",
          },
          // 委托标段
          {
            type: "precativeOrgCode",
            mode: "default",
          },
          //日期
          {
            type: "calendar",
          },
        ];
      },
    },
    equTypeValue: {
      type: [String, Number],
      default: "1",
    },
  },
  components: {
    bjSelect,
    bjRangeCalendar,
  },
  computed: {
    computedSourceMap() {
      let { map, effectiveMap, relationshipField } = this;
      this.choosedValue = {};
      let validMap = map.filter((v) => {
        if (!effectiveMap.includes(v.type) && v.type != "calendar") {
          console.error(`Type ${v.type} is not in [${effectiveMap}]`);
        }
        return effectiveMap.includes(v.type);
      });
      let relationshipMap = validMap.map((v) => {
        v = Object.assign(v, relationshipField[v.type]);
        return v;
      });
      return relationshipMap;
    },
  },
  watch: {
    computedSourceMap: {
      handler() {
        this.getSelectData();
      },
      deep: true,
      immediate: true,
    },
  },
  data() {
    return {
      //列表数据
      list: {},
      //登录参数
      login: {},
      //有效的map=>key值
      effectiveMap: ["block", "precativeOrgCode"],
      //字段关系表
      relationshipField: {
        //检测单位
        block: {
          //接口方法名
          apiName: "getTestUnitByUserIdAndTenantCode",
          //替换字段关系
          replaceFields: { key: "orgCode", label: "orgName" },
          //接口入参
          params: {
            //租户id
            tenantCode: "login&tenantCode",
            //用户id
            userId: "login&userId",
          },
          //列表数据
          list: [],
          result: "data&result",
        },
        //委托标段
        precativeOrgCode: {
          //接口方法名
          apiName: "getBlockList",
          //替换字段关系
          replaceFields: { key: "orgCode", label: "orgName" },
          //接口入参
          params: {
            //租户id
            tenantCode: "login&tenantCode",
            //用户id
            userId: "login&userId",
          },
          //列表数据
          list: [],
          result: "data&result",
        },
      },
      //已选择的数据集合
      choosedValue: {},
      //loding
      loading: {},
    };
  },
  mounted() {},
  methods: {
    //查询标段列表接口
    getTestUnitByUserIdAndTenantCode,
    getBlockList,

    //监听select选择
    conditionChange(value, type) {
      let index = -1;
      this.computedSourceMap.forEach((v, i) => {
        if (v.type == type) {
          index = i;
        }
      });
      let mapData = this.computedSourceMap.filter((v, i) => i > index);
      this.$set(this.choosedValue, type, value);
      this.getSelectData(mapData);
    },

    //查询数据
    async getSelectData(mapSourceData = this.computedSourceMap) {
      //获取登录相关信息
      this.login = getLoginData();

      //reduce结合promise队列顺序执行接口
      await mapSourceData.reduce(async (promiseChain, currentFunction) => {
        this.$set(this.loading, currentFunction.type, true);
        await promiseChain;
        //获取接口所需参数
        let params = this.dealParams(currentFunction.params);

        return new Promise((resolve) => {
          promiseChain.then(
            this[currentFunction.apiName](params)
              .then((res) => {
                let responseData = this.dealResponse(
                  res,
                  currentFunction.result
                );
                //清空已选值
                if (this.choosedValue[currentFunction.type]) {
                  this.$set(this.choosedValue, currentFunction.type, undefined);
                } else if (
                  currentFunction.isDefault &&
                  !this.choosedValue[currentFunction.type]
                ) {
                  let initValue = null;
                  if (currentFunction.mode == "tags") {
                    initValue =
                      responseData.length == 0
                        ? undefined
                        : [
                            {
                              key: responseData?.[0]?.[
                                this.relationshipField[currentFunction.type]
                                  .replaceFields.key
                              ],
                              value:
                                responseData?.[0]?.[
                                  this.relationshipField[currentFunction.type]
                                    .replaceFields.label
                                ],
                            },
                          ];
                  } else {
                    initValue =
                      responseData.length == 0
                        ? undefined
                        : {
                            key: responseData?.[0]?.[
                              this.relationshipField[currentFunction.type]
                                .replaceFields.key
                            ],
                            value:
                              responseData?.[0]?.[
                                this.relationshipField[currentFunction.type]
                                  .replaceFields.label
                              ],
                          };
                  }
                  this.$set(this.choosedValue, currentFunction.type, initValue);
                } else {
                  this.$set(this.choosedValue, currentFunction.type, undefined);
                }
                this.$set(this.list, currentFunction.type, responseData);
                resolve(res);
              })
              .catch((_) => {
                this.$set(this.list, currentFunction.type, []);
              })
              .finally((_) => {
                //关闭loading
                this.$set(this.loading, currentFunction.type, false);
              })
          );
        });
      }, Promise.resolve());

      //
      this.$emit("conditionChange", this.choosedValue);
    },

    //处理接口入参
    dealParams(params = "") {
      let allParams = {};
      try {
        Object.keys(params).map((key) => {
          let paramsPath = params[key].split("&");
          let paramValue = paramsPath.reduce((pre, item) => {
            return pre[item] || "";
          }, this);
          //兼容多选
          if (Array.isArray(paramValue)) {
            let keys = paramValue
              .map((v) => v.key)
              .filter((v) => v)
              .toString();
            allParams[key] = keys;
          } else if (
            Object.prototype.toString.call(paramValue) === "[object Object]"
          ) {
            //单选
            allParams[key] = paramValue?.key || "";
          } else {
            //兼容单个值（登录）
            allParams[key] = paramValue;
          }
        });
        throw allParams;
      } catch (params) {
        return params || {};
      }
    },

    //处理接口返回
    dealResponse(res, resultMap = "") {
      let map = resultMap.split("&");
      return map.reduce((pre, item) => {
        return pre[item];
      }, res);
    },

    //日期选择回调事件
    calendarOk() {
      this.$emit("conditionChange", this.choosedValue);
    },

    //日期范围发生变化
    calendarChange(dates = []) {
      if (dates.length == 0) {
        this.$emit("input", []);
        this.$emit("conditionChange", this.choosedValue);
      }
    },
  },
  destroyed() {
    this.choosedValue = {};
  },
};
</script>

<style lang="less" scoped>
.associativeSelectGroup-container {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
}
</style>
